#ifndef BASE_CTTCPCLIENTTASK_H_
#define BASE_CTTCPCLIENTTASK_H_

#include "ct_noncopyable.h"
#include "ctType.h"
#include "ctTime.h"
#include "ctSocket.h"
#include "Zebra.h"
#include <string>
#include "ct_log_macro.h"

class ctTCPClientTask : public ctProcessor, private ctNoncopyable
{
        public:
                enum TerminateMethod
                {
                        TM_no,
                        TM_sock_error,
                        TM_service_close
                };

                enum ConnState
                {
                        close    =  0,
                        checkconnect,
                        sync,
                        okay,
                        recycle
                };

                ctTCPClientTask(const std::string &ip,
                                const WORD port,
                                const bool compress = false)
                        : socket_pointer_(NULL), compress_(compress), ip_(ip), port_(port), tick_timer_(1200)
                {
                        state_ = close;
                        terminate_ = TM_no;
                        main_loop_ = false;
                        fdsradd_ = false; 
                        is_del_ = false;
                }

                virtual ~ctTCPClientTask() 
                {
                        final();
                }

                void final()
                {
                        CT_TRACE(__PRETTY_FUNCTION__);
                        SAFE_DELETE(socket_pointer_);
                        terminate_ = TM_no;
                        main_loop_ = false;
                }

                bool isTerminate() const
                {
                        return TM_no != terminate_;
                }

                void Terminate(const TerminateMethod method)
                {
                        terminate_ = method;
                }

                bool checkFirstMainLoop()
                {
                        if (main_loop_) {
                                return false;
                        }
                        else {
                                main_loop_ = true;
                                return true;
                        }
                }

                const ConnState getState() const
                {
                        return state_;
                }

                void setState(const ConnState state)
                {
                        this->state_ = state;
                }

                const char *getStateString(const ConnState state)
                {
                        const char *retval = NULL;

                        switch(state) {
                                case close:
                                        retval = "close";
                                        break;
                                case checkconnect:
                                        retval = "checkconnect";
                                        break;
                                case sync:
                                        retval = "sync";
                                        break;
                                case okay:
                                        retval = "okay";
                                        break;
                                case recycle:
                                        retval = "recycle";
                                        break;
                        }

                        return retval;
                }

                virtual void clone(ctTCPClientTask* task)
                {
                }
                void addEpollFD(int kdpfd,__uint32_t events, void* ptr)
                {
                        socket_pointer_->addEpoll(kdpfd,events, ptr);
                }
                void delEpollFD(int kdpfd,__uint32_t events)
                {
                        socket_pointer_->delEpoll(kdpfd, events);
                }
                bool checkStateTimeout(const ConnState state,const ctTime &ct, const time_t timeout) const
                {
                        if (state == this->state_)
                                return (life_time_.elapse(ct) >= timeout);
                        else
                                return false;
                }

                virtual int checkRebound()
                {
                        return 1;
                }

                virtual void recycleConn() {};

                virtual void addToContainer() {};

                virtual void removeFromContainer() {};

                virtual bool connect();

                void delMe()
                { 
                        is_del_ = true;
                };
                bool isDel() const 
                {
                        return is_del_;
                }

                void checkConn();
                bool sendCmd(const void *pstrCmd,const int nCmdLen);
                bool ListeningRecv(bool);
                bool ListeningSend();

                void getNextState();
                void resetState();
                void reconn();
                bool isFdsrAdd()
                {
                        return fdsradd_;
                }
                bool fdsrAdd(bool set=true)
                {
                        fdsradd_=set;
                        return fdsradd_;
                }
                bool checkTick() const
                {
                        return tick_;
                }

                void clearTick()
                {
                        tick_ = false;
                }

                void setTick()
                {
                        tick_ = true;
                }
                int sock()
                { 
                        return socket_pointer_->Sock();
                }
                const std::string getIP() const 
                { 
                        return ip_; 
                }
                const WORD getPort() const 
                {
                        return port_; 
                }
        protected:

                ctSocket *socket_pointer_;
                volatile ConnState state_;
                const bool compress_;

        public:
                const std::string ip_;
                const WORD port_;
        private:
                bool fdsradd_;
                ctTime life_time_;
                TerminateMethod terminate_;
                volatile bool main_loop_;
                Timer tick_timer_;
                bool tick_;
                bool is_del_;
}; 
#endif //BASE_CTTCPCLIENTTASK_H_
